package com.pku.smart.controller;

import com.alibaba.fastjson.JSON;
import com.pku.smart.config.IIHApiConfig;
import com.pku.smart.log.MyLog;
import com.pku.smart.service.SI0057Service;
import com.pku.smart.service.SI0058Service;
import com.pku.smart.service.SI0070Service;
import com.pku.smart.service.SmartPayService;
import com.pku.smart.trade.service.IPaymentManagerService;
import com.pku.smart.trade.vopackage.*;
import com.pku.smart.utils.DateUtil;
import com.pku.smart.vopackage.VoReqGetNoPay;
import com.pku.smart.vopackage.VoResGetNoPay;
import com.pku.smart.vopackage.si0057.VoReqIIH0057Param;
import com.pku.smart.vopackage.si0057.VoResIIH0057Result;
import com.pku.smart.vopackage.si0058.VoReqIIH0058ParamDataEntinfoPresinfoPresitm;
import com.pku.smart.vopackage.si0058.VoResIIH0058Result;
import com.pku.smart.vopackage.si0058.VoResIIH0058ResultDataEntinfo;
import com.pku.smart.vopackage.si0058.VoResIIH0058ResultDataEntinfoPresinfoPresitm;
import com.pku.smart.vopackage.si0070.VoResIIH0070Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Controller
public class IndexController {

    private static final MyLog _log = MyLog.getLog(IndexController.class);

    @Autowired
    IIHApiConfig config;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    SmartPayService payService;

    @Autowired
    SI0057Service si0057Service;

    @Autowired
    SI0058Service si0058Service;

    @Autowired
    SI0070Service si0070Service;

    @Autowired
    IPaymentManagerService paymentManagerService;

    @RequestMapping("/preview")
    public String preview(@ModelAttribute VoReqGetNoPay requestVo, BindingResult bindingResult, Model model, HttpServletRequest request) {
        _log.info("接受到：" + JSON.toJSONString(requestVo));

        //1、验证调用是微信还是支付宝
        String ua = request.getHeader("User-Agent");
        if (StringUtils.isBlank(ua)) {
            model.addAttribute("errorMessage", "系统错误");
            return "fail";
        }
        String client = null;
        String channelId = "ALIPAY_WAP";
        if (ua.contains("Alipay")) {
            client = "alipay";
            channelId = "ALIPAY_WAP";
        } else if (ua.contains("MicroMessenger")) {
            client = "wx";
            channelId = "WX_JSAPI";
            model.addAttribute("errorMessage", "请使用支付宝扫一扫");
            return "fail";
        }
        if (client == null) {
            String errorMessage = "请用微信或支付宝扫码";
            model.addAttribute("errorMessage", errorMessage);
            //return "fail";
        }

        //2、校验IIH传过来的参数
        payService.validateParams(requestVo, bindingResult);

        //3、调用IIH提取费用 调入待缴费用
        VoReqIIH0057Param param = new VoReqIIH0057Param();
        param.setCode_user(config.getCode_user());
        param.setCode_dep(requestVo.getCode_dep());
        param.setCode_external(config.getCode_external());
        param.getData().setCode_pat(requestVo.getCode_pat());
        param.getData().setCode_hospital(config.getCode_hospital());
        param.getData().setCode_enttp(config.getCode_enttp());
        param.getData().setTimes_op(requestVo.getTimes_op());
        VoResIIH0057Result result = si0057Service.process(param);
        if (!"0".equals(result.getCode())){
            String errorMessage = result.getMsg();
            model.addAttribute("errorMessage", errorMessage);
            return "fail";
        }

        //4、划价并存redis
        VoResIIH0058Result result0058 = si0058Service.process(param,result);
        if (!"0".equals(result0058.getCode())){
            String errorMessage = result0058.getMsg();
            model.addAttribute("errorMessage", errorMessage);
            return "fail";
        }
        List<VoResIIH0058ResultDataEntinfo> list = result0058.getData().getEntinfos().getEntinfo();

        //5、组织前台展示数据
        List<VoResGetNoPay> listOrder = new ArrayList<>();
        VoResIIH0058ResultDataEntinfo entinfo = list.get(0);
        entinfo.getPresinfos().getPresinfo().forEach(x->{
            List<VoResIIH0058ResultDataEntinfoPresinfoPresitm> presitmList = x.getPresitms().getPresitm();
            presitmList.forEach(xx->{
                VoResGetNoPay noPay = new VoResGetNoPay();
                noPay.setPatCode(requestVo.getCode_pat());
                noPay.setPatName("测试");
                noPay.setEntCode(entinfo.getCode_ent());
                noPay.setEntAmout(Long.valueOf(entinfo.getAmt_ent()));
                noPay.setApplyCode(x.getCode_apply());
                noPay.setOperaCode(config.getCode_user());
                noPay.setPayNO(result0058.getData().getPayno());
                noPay.setOrName(xx.getName_srv());
                noPay.setDeptName(x.getName_dep_or());
                noPay.setDoctorName(x.getName_emp_or());
                noPay.setPresAmt(xx.getAmt());
                listOrder.add(noPay);
            });
        });
        VoResGetNoPay order = listOrder.get(0);

        //设置页面显示数据
        model.addAttribute("order", order);
        model.addAttribute("list", listOrder);

        //缓存划价数据
        String cachekey = order.getPayNO();
        redisTemplate.opsForValue().set(cachekey, result0058, 10, TimeUnit.MINUTES);

        //跳转页面
        return "preview";
    }

    @RequestMapping("/pay")
    public void pay(@ModelAttribute VoResGetNoPay requestVo, HttpServletResponse response) {
        _log.info("pay接受到：" + JSON.toJSONString(requestVo));

        //从缓存取划价数据
        String cachekey = requestVo.getPayNO();
        _log.info("从redis缓存获取数据：" + cachekey);
        VoResIIH0058Result result0058 = (VoResIIH0058Result)redisTemplate.opsForValue().get(cachekey);

        //调用支付宝wap支付
        VoReqPayWap req = new VoReqPayWap();
        req.setMchId("10000000");
        req.setChannelId("ALIPAY_WAP");
        req.setMchOrderNo("P" + DateUtil.getSeqString());
        req.setTotalAmount(requestVo.getEntAmout());
        req.setSubject("门诊缴费");
        req.setBody(result0058.getMsg());
        req.setClientIp("127.0.0.1");
        req.setReturnUrl("http://smart.free.idcfengye.com/success?mchOrderNo="+req.getMchOrderNo()+"&mchId="+req.getMchId()+"&payNO="+cachekey);
        req.setQuitUrl("http://127.0.0.1");
        req.setNotifyUrl("http://smart.free.idcfengye.com/success");
        req.setSign("q4r");

        //调用服务
        VoResTradePayment payResultVo = paymentManagerService.wapPay(req);
        VoResPayWap resPayWap = (VoResPayWap) payResultVo.getRetData();
        String form = resPayWap.getCodeUrl();
        response.setContentType("text/html;charset=utf-8");
        try {
            response.getWriter().write(form);//直接将完整的表单html输出到页面
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/fail")
    public String fail(Model model, HttpServletRequest request) {
        _log.info("fail");
        //看看是否已支付 考虑撤销
        return "fail";
    }

    @RequestMapping("/success")
    public String success(@ModelAttribute VoResGetNoPay requestVo,Model model, HttpServletRequest request) {
        _log.info("success接受到：" + JSON.toJSONString(requestVo));
        //查询订单时是否成功

        //支付成功了 从redis获取划价数据 调用缴费
        String cachekey = requestVo.getPayNO();
        _log.info("从redis缓存获取数据：" + cachekey);
        VoResIIH0058Result result0058 = (VoResIIH0058Result)redisTemplate.opsForValue().get(cachekey);

        //开始提交结算数据
        VoResIIH0070Result result = si0070Service.process(result0058);

        String errorMessage = "支付成功";
        model.addAttribute("errorMessage", errorMessage);
        return "success";
    }
}
